package org.aplikator.server;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.activation.FileTypeMap;
import javax.activation.MimeType;
import javax.activation.MimeTypeParseException;
import javax.activation.MimetypesFileTypeMap;
import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

import com.sun.media.jai.codec.ByteArraySeekableStream;

public class ImageResizer {

    private static final Logger LOG = Logger.getLogger(ImageResizer.class.getName());

    /**
     * Resize the input picture (byte array) to fit the given maximum size.
     * Supports JPEG, PNG, GIF and TIFF. For other file types returns null.
     *
     * @param input
     * @param filename
     * @param maxSize
     * @return JPEG encoded byte array of resized picture
     */
    public static byte[] resize(byte[] input, String filename, int maxSize) {
        byte[] retval = null;
        if (input == null) {
            return null;
        }
        try {
            MimeType mimeType = getMimeType(filename);
            if (!"image".equals(mimeType.getPrimaryType())) {
                return null;
            }
            // TIFF must be converted to JPEG
            if (mimeType.getSubType().equals("tiff")) {
                RenderedOp src = JAI.create("stream", new ByteArraySeekableStream(input));
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                JAI.create("encode", src, stream, "JPEG", null);
                input = stream.toByteArray();
                stream.close();
            }
            // calculate resizing
            ImageIcon sourceIcon = new ImageIcon(input);
            int originalX = sourceIcon.getIconWidth();
            int originalY = sourceIcon.getIconHeight();
            if (originalX <= maxSize && originalY <= maxSize) {
                retval = input;
            } else {
                int calculatedX;
                int calculatedY;
                if (originalX >= originalY) {
                    calculatedX = maxSize;
                    float ratio = originalX / (float) maxSize;
                    calculatedY = Math.round(originalY / ratio);
                } else {
                    calculatedY = maxSize;
                    float ratio = originalY / (float) maxSize;
                    calculatedX = Math.round(originalX / ratio);
                }
                // scale the image
                Image sourceImage = sourceIcon.getImage();
                sourceImage = sourceImage.getScaledInstance(calculatedX, calculatedY, Image.SCALE_AREA_AVERAGING);
                MediaTracker mediaTracker = new MediaTracker(new JLabel());
                mediaTracker.addImage(sourceImage, 0);
                mediaTracker.waitForAll();
                // encode output as JPEG
                BufferedImage outputImage = new BufferedImage(calculatedX, calculatedY, BufferedImage.TYPE_INT_RGB);
                Graphics graphics = outputImage.createGraphics();
                graphics.drawImage(sourceImage, 0, 0, null);
                graphics.dispose();
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                retval = outputStream.toByteArray();
                ImageIO.write(outputImage, "jpg", outputStream);
                retval =  outputStream.toByteArray();
            }
        } catch (Exception ex) {
            LOG.log(Level.SEVERE, "Error in image resizer:", ex);
        }
        return retval;
    }

    private static FileTypeMap mimeTypes;

    /**
     * Determine the Mime type based on file extension
     *
     * @param fileName
     * @return
     * @throws MimeTypeParseException
     */
    public static MimeType getMimeType(String fileName) throws MimeTypeParseException {

        if (fileName == null) {
            return new MimeType("application", "octet");
        }
        if (mimeTypes == null) {
            mimeTypes = FileTypeMap.getDefaultFileTypeMap();
            ((MimetypesFileTypeMap) mimeTypes).addMimeTypes("application/msword doc DOC");
            ((MimetypesFileTypeMap) mimeTypes).addMimeTypes("application/vnd.ms-excel xls XLS");
            ((MimetypesFileTypeMap) mimeTypes).addMimeTypes("application/pdf pdf PDF");
            ((MimetypesFileTypeMap) mimeTypes).addMimeTypes("text/xml xml XML");
        }

        return new MimeType(mimeTypes.getContentType(fileName));

    }

}

/*
 *
 * BufferedImage image = ImageIO.read(new File("c:\picture.jpg"));
 *
 *
 * private static BufferedImage resize(BufferedImage image, int width, int
 * height) { BufferedImage resizedImage = new BufferedImage(width, height,
 * BufferedImage.TYPE_INT_ARGB); Graphics2D g = resizedImage.createGraphics();
 * g.drawImage(image, 0, 0, width, height, null); g.dispose(); return
 * resizedImage; }
 *
 * ImageIO.write(resized, "png", new File("c:\picture1.png"));
 *
 *
 * private static BufferedImage resize(BufferedImage image, int width, int
 * height) { int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB :
 * image.getType(); BufferedImage resizedImage = new BufferedImage(width,
 * height, type); Graphics2D g = resizedImage.createGraphics();
 * g.setComposite(AlphaComposite.Src);
 *
 * g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
 * RenderingHints.VALUE_INTERPOLATION_BILINEAR);
 *
 * g.setRenderingHint(RenderingHints.KEY_RENDERING,
 * RenderingHints.VALUE_RENDER_QUALITY);
 *
 * g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
 * RenderingHints.VALUE_ANTIALIAS_ON);
 *
 * g.drawImage(image, 0, 0, width, height, null); g.dispose(); return
 * resizedImage; }
 *
 *
 * PDF: https://pdf-renderer.dev.java.net/examples.html
 */
